package com.example.learnjpegjavafx;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;

import java.io.IOException;

public class HelloApplication extends Application {
    @Override
    public void start(Stage stage) throws IOException {
        FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
        Scene scene = new Scene(fxmlLoader.load(), 320, 240);
        stage.setTitle("Hello!");
        stage.setScene(scene);
        stage.show();
        int[][] p = new int[8][8];
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                p[i][j] = i * 8 + j;
                System.out.print(String.format("%d, ", p[i][j]));
            }
            System.out.println();
        }
        System.out.println();

        double result[][] = FDCTTrans(p);
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                System.out.print(String.format("%.2f, ", result[i][j]));
            }
            System.out.println();
        }
        System.out.println();
        double pixelsForResult[][] = FDCTReverseTrans(result);
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                System.out.print(String.format("%.2f, ", pixelsForResult[i][j]));
            }
            System.out.println();
        }
    }

    //http://zhaoxuhui.top/blog/2018/05/26/DCTforImageDenoising.html
    //把图像信号从“时域”转换为“频域”，类似于傅立叶变换
    private double[][] FDCTTrans(int[][] pixels) {
        double uv[][] = new double[8][8];
        for (int u = 0; u < 8; u++) {
            for (int v = 0; v < 8; v++) {
                double sum = 0;
                for (int i = 0; i < 8; i++) {
                    for (int j = 0; j < 8; j++) {
                        sum += pixels[i][j] * Math.cos(Math.toRadians((2 * i + 1) * 3.1415926f / 2f * 8 * u)) *
                                Math.cos(Math.toRadians((2 * j + 1) * 3.1415926f / 2f * 8 * v));
                    }
                }
                uv[u][v] = Math.sqrt((u == 0 ? 1 : 2) / 8f) * Math.sqrt((v == 0 ? 1 : 2) / 8f) * sum;
            }
        }
        return uv;
    }

    //DCT 逆向变换
    private double[][] FDCTReverseTrans(double[][] uv) {
        double pixels[][] = new double[8][8];
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                double sum = 0;
                for (int u = 0; u < 8; u++) {
                    for (int v = 0; v < 8; v++) {
                        sum += Math.sqrt((u == 0 ? 1 : 2) / 8f) * Math.sqrt((v == 0 ? 1 : 2) / 8f) * uv[u][v] *
                                Math.cos(Math.toRadians((2 * i + 1) * 3.1415926f / 2f * 8 * u)) *
                                Math.cos(Math.toRadians((2 * j + 1) * 3.1415926f / 2f * 8 * v));
                    }
                }
                pixels[i][j] = sum;
            }
        }
        return pixels;
    }

    public static void main(String[] args) {
        launch();
    }
}